package com.oe.market.modules.common.model;

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

public abstract class ADaoBase<THIS extends BaseBean> extends BaseDao{
    private static final Logger log = LoggerFactory.getLogger(BaseDao.class);
    public abstract THIS getThisClassInstance();

    public abstract String getTableName();

    // 查询所有
    public List<THIS> find() throws SQLException {
        String sql="select * from `"+ getTableName() + "`;";
        return find(sql);
    }

    protected List<THIS> find(String sql) throws SQLException {
        Connection conn = BaseDao.getConnection();
        PreparedStatement stmt = conn.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery();
        List<THIS> ret = new ArrayList<>();
        while(rs.next()) {
            Field[] fields = this.getThisClassInstance().getClass().getDeclaredFields();
            Map<String, Object> map = new HashMap();
            for (Field field : fields) {
                try {
                    // check params
                    map.put(field.getName(), rs.getObject(getKeyName(field)));
                }
                catch (Exception e) {
//                    e.getMessage()
                }
            }
            if (0 == map.size()) {
                continue;
            }
            ret.add(query(map));
        }
        BaseDao.closeAll(conn, stmt, rs);
        return ret;
    }


    protected String update(String sql) {
        try {
            int ret = executeSql(sql);
            if (0 == ret) {
                return "更新信息失败";
            }
        } catch (SQLException e) {
            return "更新信息失败";
        }
        return null;
    }
    // 插入名单
    public String append(THIS obj) {
        String sql = getAppendSql(obj);
        try {
            if (1 != executeSql(sql)) {
                return "添加失败";
            }
        } catch (SQLException e) {
            log.error(e.getMessage() + "【sql:" + sql + "】");
            e.printStackTrace();
            return e.getMessage();
        }
        return null;
    }

    public String appends(List<THIS> list){
        Map ret = new HashMap<>();

        // append;
        Iterator iter = list.iterator();
        while(iter.hasNext()) {
            String temp = append((THIS) iter.next());
            if (null != temp) {
                ret.put(iter.next().toString(), temp);
            }
        }

        // return ;
        if (ret.size() != 0) {
            Gson gson = new Gson();
            return gson.toJson(ret);
        }
        return null;
    }

    /// 添加
    private String getAppendSql(THIS _obj){
        StringBuilder sqlKey = new StringBuilder("INSERT INTO `" + getTableName() + "` (");
        String sqlKeyEnd = ")";
        StringBuilder sqlValue = new StringBuilder(" VALUES(");
        String sqlValueEnd = ");";

        Field[] fields = _obj.getClass().getDeclaredFields();

        int paramNumber = 0;
        for (Field field : fields) {
            try {
                // check params
                Object obj = field.get(_obj);
                if (null == obj ||
                        (obj.getClass().getName().equals("java.lang.Integer")
                                && 0 == (Integer) obj)) {
                    continue;
                }

                // split ,
                if (0 != paramNumber) {
                    sqlKey.append(",");
                    sqlValue.append(",");
                }

                // key name
                sqlKey.append("`").append(getKeyName(field)).append("`");

                // value
                sqlValue.append("'").append(field.get(_obj)).append("'");
                ++paramNumber;
            } catch (IllegalAccessException e) {
                log.error(e.getMessage());
                e.printStackTrace();
            }
        }

        return sqlKey + sqlKeyEnd + sqlValue + sqlValueEnd;
    }



    protected THIS query(Map map) {
        THIS obj = getThisClassInstance();
        for (Object key : map.keySet()) {
            try {
                obj.setProperty((String) key, map.get(key));
            } catch (Exception e) {
                log.error(e.getMessage());
                log.error("request: " + new Gson().toJson(map));
                System.out.println(e.getMessage());
            }
        }
        return obj;
    }

    protected String getKeyName(Field field) {
        SerializedName serializedName = field.getAnnotation(SerializedName.class);
        if (null != serializedName) {
            return serializedName.value();
        }
        return field.getName();
    }
}
